﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Platform.LanguageProcessing.Expressions;

namespace Platform.LanguageProcessing
{

	/// <summary>
	/// Contexto de execução do parser
	/// </summary>
	public sealed class ParserContext 
	{
		/// <summary>
		/// 
		/// </summary>
		/// <param name="parser"></param>
		/// <param name="scanner"></param>
		internal ParserContext( SyntaxAnalyzer analyzer, Parser parser, Scanner scanner )
		{
			this.Parser = parser;
			this.Scanner = scanner;
			this.Expressions = new GrammarParserStack();
			this.Analyser = analyzer;
		}

		/// <summary>
		/// 
		/// </summary>
		public Scanner Scanner
		{ get; private set; }

		/// <summary>
		/// 
		/// </summary>
		public Parser Parser
		{ get; private set; }

		/// <summary>
		/// 
		/// </summary>
		public SyntaxAnalyzer Analyser
		{ get; private set; }

		public GrammarParserStack Expressions
		{ get; private set; }


		public IEnumerable<GrammarExpression> PopUntil( Func<GrammarExpression, bool> predicate )
		{
			while ( !this.Expressions.IsEmpty
				&& !predicate( this.Expressions.Peek() ) )
			{
				yield return this.Expressions.Pop();
			}
		}

		public SentenceExpression PopSentence()
		{
			if ( this.Expressions.IsEmpty )
			{
				throw new InvalidOperationException();
			}

			var expression = this.Expressions.Pop() as SentenceExpression;

			if ( expression == null || !this.Expressions.IsEmpty )
			{
				throw new InvalidOperationException();
			}

			return expression;
		}
	}

}
